//
// RS Game Framework
// Copyright © 2009 Jedd Haberstro
// jhaberstro@gmail.com
// 
// $Id:
//

#ifndef RS_THREAD_HPP
#define RS_THREAD_HPP

#include "rs/Core.hpp"
#include "rs/MetaFacilities.hpp"
#include "rs/Portability.hpp"
#include "rs/SmartPointer.hpp"

namespace rs
{
    typedef void (*ThreadFunction) (void*);
    
    namespace internal
    {
        struct ThreadImplementation;
        struct ThreadIDImplementation;
        
        struct ThreadFunc
        {
            ThreadFunc() {
            }
            
            ThreadFunc(ThreadFunction f, IntPtr id)
            : func(f), typeId(id) {
            }
            
            ThreadFunction func;
            IntPtr typeId;
        };
    }
    
    class Thread;
    class ThreadID
    {
        friend class Thread;
        
    public:
        
        ThreadID();
        
        ThreadID(ThreadID const& other);
        
        ~ThreadID();
        
        ThreadID& operator=(ThreadID const& other);
                
        Boolean operator==(ThreadID const& other) const;

        Boolean operator!=(ThreadID const& other) const;
        
    protected:
        
        internal::ThreadIDImplementation* implementation_;
    };
    
    
    class Thread
    {
        friend class internal::ThreadImplementation;
        
    private:

        typedef SmartPointer< internal::ThreadImplementation > ThreadImplementationPtr;
        
    public:

        static ThreadID GetCurrentID();
        
        static void Sleep(UInt64 seconds, UInt64 nanoseconds);
        
        static void Yield();
        
        Thread();

        explicit Thread(ThreadFunction function);
        
        Thread(Thread const& other);
                
        ~Thread();
        
        void Start(void* arg = 0);

        void Join();
        
        void Detach();
                
        ThreadID GetID() const;
        
        Boolean IsRunning() const;
        
        void Swap(Thread& other);
        
        Thread& operator=(Thread const& other);
        
    protected:
        
        internal::ThreadFunc func_;
        ThreadImplementationPtr implementation_;
        Boolean launched_;
    };
    
    
    inline Boolean Thread::IsRunning() const {
        return launched_;
    }
}



#endif // RS_THREAD_HPP
